package org.linlinjava.litemall.admin.service;

import com.alibaba.druid.support.json.JSONUtils;
import com.github.pagehelper.util.StringUtil;
import org.linlinjava.litemall.admin.dto.BusinessProjectDetail;
import org.linlinjava.litemall.admin.util.AdminCheck;
import org.linlinjava.litemall.admin.util.AdminStringUtil;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.core.util.YwcgEnumUtil;
import org.linlinjava.litemall.db.domain.*;
import org.linlinjava.litemall.db.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * @Author: Daisen.Z
 * @Date: 2021/6/3 18:15
 * @Version: 1.0
 * @Description:
 */
@Service
public class AdBusinessProjectService {

    @Autowired
    private BusinessProjectService projectService;

    @Autowired
    private BusinessPersonService personService;

    @Autowired
    private BusinessResultService businessResultService;


    @Autowired
    private AdBusinessAuditService businessAuditService;

    @Autowired
    private ProjectFileService projectFileService;

    @Autowired
    private LogHelper logHelper;


    public Object querySelective(String year, String name, String type, Integer statusAudit, String dutyPeopleName,Integer page, Integer limit, String sort, String order) {
        String peopleName = AdminCheck.isSuperUser();

        // 如果角色中不包含超级管理员，则只能查自己参与的和自己录入的
        if (!StringUtils.isEmpty(peopleName)) {
            // 先通过自己的名字和模块代号查询出自己相关的项目ids
            List<String> projectIds = personService.selectOwnPorjietidsByOwnNameAndModel(peopleName, YwcgEnumUtil.ModelNameCode.KYP.getCode());
            //if (CollectionUtils.isEmpty(projectIds)) { // 如果没有查询到与自己相关的项目信息，返回空集合
            //    return ResponseUtil.okList(new ArrayList<BusinessProject>());
            //}
            // 然后通过项目的ids查询自己的项目
            List<BusinessProject> projectList = projectService.querySelectiveByPojectIds(peopleName, projectIds, year, name, type, statusAudit, dutyPeopleName,page, limit, sort, order);
            return ResponseUtil.okList(projectList);
        }
        // 超管可以查询所有
        List<BusinessProject> projectList = projectService.querySelective(year, name, type, statusAudit, dutyPeopleName,page, limit, sort, order);
        return ResponseUtil.okList(projectList);
    }


    @Transactional
    public Object delete(BusinessProject businessProject) {
        String projectId = businessProject.getProjectId();
        if (projectId == null) {
            logHelper.logOrderFail("删除","删除项目失败-未找到项目:"+businessProject.getProjectName());
            return ResponseUtil.badArgument();
        }
        // 1.先判断是不是超级管理员或者是项目负责人,不是超管和项目负责人不能删除该项目
        String userName = AdminCheck.isSuperUser();
        if (StringUtil.isNotEmpty(userName)) { // userName不是空证明不是超管
            if (!userName.equals(businessProject.getDutyPersonalName()) && !userName.equals(businessProject.getAdminName())) { // 不是负责人和录入人无权操作
                return ResponseUtil.unauthz();// 提示无操作权限
            }
            // 判断项目是否是审核中的状态，审核中的项目和审核通过的项目只有超管能编辑和删除
            if (!businessAuditService.canEdit(projectId, YwcgEnumUtil.ModelNameCode.KYP.getCode())) { // 如果不能编辑
                logHelper.logOrderFail("删除","删除项目失败-项目已审核:"+businessProject.getProjectName());
                return ResponseUtil.fail(999, "审核中或审核通过的项目不能删除，如需删除请联系超管");
            }
        }
        // 2. 如果有权限删除，则删除所有依赖于项目的成果、项目成员中间表和项目
        // 先删除项目成果
        businessResultService.deleteByProjectId(projectId);
        // 再删除项目附近
        projectFileService.deleteByProjectId(projectId);
        // 再删除项目成员
        personService.deleteByProjectId(projectId);
        // 最后再删除项目
        projectService.deleteByProjectId(projectId);
        logHelper.logOrderSucceed("删除","删除项目:"+businessProject.getProjectName());
        return ResponseUtil.ok();
    }


    // 获取项目相关成果
    public Object getAboutResult(String projectId) {
        if (projectId == null) {
            return ResponseUtil.badArgument();
        }
        // 1. 判断是否有成果或者野外勘测依赖该项目，如果有依赖，就不能删除，提示有成果依赖于该项目
        List<BusinessResult> businessResults = businessResultService.selectByProjectId(projectId);
        return ResponseUtil.okList(businessResults);
    }


    // 添加项目信息
    @Transactional
    public Object create(BusinessProjectDetail businessProjectDetail) {
        // 1. 先生成项目的UUID
        String projectId = AdminStringUtil.get32UUID();
        // 2. 添加项目成员，关连项目UUID，同时找出项目负责人（项目负责人有且只能有一个）
        List<BusinessPerson> personList = businessProjectDetail.getPersonList();

        // 记录项目负责人,因为项目中也要添加负责人
        String dutyName = null;
        if (!CollectionUtils.isEmpty(personList)) {
            for (BusinessPerson businessPerson : personList) {

                // 判断是不是负责人,如果是就记录下名字
                if (YwcgEnumUtil.PersonDutyNameCode.FIRST.getCode() == businessPerson.getPersonDuty()) {
                    // 如果名字不为空证明已有负责人，把重复的负责人默认置为主要完成人
                    if (dutyName != null) {
                        businessPerson.setPersonDuty(YwcgEnumUtil.PersonDutyNameCode.SECOND.getCode());
                    }else {
                        dutyName = businessPerson.getPersonName();
                    }
                }

                // 设置角色名称
                businessPerson.setPersonDutyName(YwcgEnumUtil.PersonDutyNameCode.getName(businessPerson.getPersonDuty()));
                // 设置基本信息,录入人、录入时间等
                AdminStringUtil.setAdminInsertInfo(businessPerson);

                // 关联项目UUID,设置模块信息以及自己的UUID
                businessPerson.setProjectId(projectId);
                businessPerson.setProjectName(businessProjectDetail.getBusinessProject().getProjectName());
                businessPerson.setPersonId(AdminStringUtil.get32UUID());
                businessPerson.setOwningModule(YwcgEnumUtil.ModelNameCode.KYP.getCode());
                businessPerson.setOwningModuleName(YwcgEnumUtil.ModelNameCode.KYP.getName());
                // 插入成员信息
                personService.insert(businessPerson);
            }
        }

        // 3. 添加附件信息
        // 记录附件名称，存到项目里面
        List<String> fileNames = new ArrayList<>();
        List<ProjectFile> projectFiles = businessProjectDetail.getProjectFileList();
        if (projectFiles != null) {

            for (ProjectFile projectFile : projectFiles) {

                if (StringUtils.isEmpty(projectFile.getFileId())) {
                    // 没有ID则证明没有上传附件，不保存
                    continue;
                }
                // 设置相关项目id
                projectFile.setProjectId(projectId);
                // 设置基本信息
                AdminStringUtil.setAdminInsertInfo(projectFile);

                if (fileNames.contains(projectFile.getFileName())) {
                    // 如果文件名称已存在，将id拼接上保证唯一
                    projectFile.setFileName(projectFile.getFileName() + "-" + projectFile.getFileId());
                }
                // 记录下文件名称
                fileNames.add(projectFile.getFileName());
                // 插入
                projectFileService.updateByPrimaryKey(projectFile);
            }

        }

        // 4. 设置项目负责人，添加项目信息
        BusinessProject businessProject = businessProjectDetail.getBusinessProject();
        AdminStringUtil.setAdminInsertInfo(businessProject);
        businessProject.setDutyPersonalName(StringUtils.isEmpty(dutyName) ? "" : dutyName);
        businessProject.setProjectId(projectId);
        businessProject.setStatusAudit(YwcgEnumUtil.StatusAuditCode.noSubmit); // 状态为待提交
        // 设置项目相关文件名称
        businessProject.setProjectFilesName(JSONUtils.toJSONString(fileNames));
        projectService.insert(businessProject);
        logHelper.logOrderSucceed("添加","添加项目:"+businessProject.getProjectName());
        return ResponseUtil.ok();
    }


    // 查询所有已审核通过的项目
    public Object queryByPass() {
        return ResponseUtil.okList(projectService.selectByStatusAudit(YwcgEnumUtil.StatusAuditCode.pass));
    }


    // 查询项目详情信息，包括项目成员、项目附件以及项目成果
    public Object detail(String projectId) {
        if (StringUtils.isEmpty(projectId)) {
            return ResponseUtil.badArgumentValue(); // 参数值不对
        }
        // 1. 查询项目信息
        BusinessProject businessProject = projectService.selectByPrimaryKey(projectId);
        // 2. 查询附件信息
        List<ProjectFile> projectFiles = projectFileService.selectByProjectId(projectId);
        // 3. 查询成员信息
        List<BusinessPerson> personList = personService.selectByProjectId(projectId);
        // 4. 查询项目相关已审核通过的成果信息
        List<BusinessResult> businessResults = businessResultService.selectByProjectIdAndAuditStatus(projectId, YwcgEnumUtil.StatusAuditCode.pass);
        // 现遍历添加基础集合,key是模块id，value是查询出的集合
        Map<Integer, List<BusinessResult>> resultMap = new HashMap<>();
        for (YwcgEnumUtil.ModelNameCode value : YwcgEnumUtil.ModelNameCode.values()) {
            int modelId = value.getCode();
            resultMap.put(modelId, new ArrayList()); // 无论有没有结果都要返回值
        }
        for (BusinessResult businessResult : businessResults) {
            // 查询到结果的替换结果信息
            resultMap.get(businessResult.getOwningModule()).add(businessResult);
        }
        BusinessProjectDetail detail = new BusinessProjectDetail();
        detail.setBusinessProject(businessProject);
        detail.setProjectFileList(projectFiles);
        detail.setPersonList(personList);
        detail.setResultMap(resultMap);
        return ResponseUtil.ok(detail);
    }


    // 更新项目
    @Transactional
    public Object update(BusinessProjectDetail businessProjectDetail) {

        BusinessProject businessProject = businessProjectDetail.getBusinessProject();
        List<ProjectFile> projectFiles = businessProjectDetail.getProjectFileList();
        List<BusinessPerson> personList = businessProjectDetail.getPersonList();

        // 判断项目是否已经审核或者正在审核中，正在审核或者审核中的项目只有超管可以修改
        if (!businessAuditService.canEdit(businessProject.getProjectId(), YwcgEnumUtil.ModelNameCode.KYP.getCode())
                && !StringUtils.isEmpty(AdminCheck.isSuperUser())) {
            return ResponseUtil.fail(999, "审核中或审核通过的项目基本信息不能修改，如需修改请联系超管");
        }

        // 1. 更新成员信息,先全部删除，再插入
        // 记录负责人
        String dutyName = null;
        // 需要先删除所有项目成员
        personService.deleteByProjectId(businessProject.getProjectId());
        for (BusinessPerson businessPerson : personList) {
            if (YwcgEnumUtil.PersonDutyNameCode.FIRST.getCode() == businessPerson.getPersonDuty()) {
                // 如果名字不为空证明已有负责人，把重复的负责人默认置为主要完成人
                if (dutyName != null) {
                    businessPerson.setPersonDuty(YwcgEnumUtil.PersonDutyNameCode.SECOND.getCode());
                }else {
                    dutyName = businessPerson.getPersonName();
                }
            }
            businessPerson.setProjectId(businessProject.getProjectId());
            businessPerson.setProjectName(businessProjectDetail.getBusinessProject().getProjectName());
            businessPerson.setPersonDutyName(YwcgEnumUtil.PersonDutyNameCode.getName(businessPerson.getPersonDuty()));
            if (!StringUtils.isEmpty(businessPerson.getPersonId())) {// 如果有id则执行更新(伪更新)
                AdminStringUtil.setAdminUpdateInfo(businessPerson);
            } else {
                // 没有id则执行插入
                AdminStringUtil.setAdminInsertInfo(businessPerson);
                businessPerson.setPersonId(AdminStringUtil.get32UUID());
                businessPerson.setOwningModule(YwcgEnumUtil.ModelNameCode.KYP.getCode());
                businessPerson.setOwningModuleName(YwcgEnumUtil.ModelNameCode.KYP.getName());
            }
            personService.insert(businessPerson);
        }
        // 2. 更新附件信息,先全部删除，再插入
        projectFileService.deleteByProjectId(businessProject.getProjectId());
        List<String> fileNames = new ArrayList<>();
        for (ProjectFile projectFile : projectFiles) {

            if (StringUtils.isEmpty(projectFile.getFileId())) {
                // 没有ID则证明没有上传附件，不保存
                continue;
            }

            if (fileNames.contains(projectFile.getFileName())) {
                // 如果文件名称已存在，将id拼接上保证唯一
                projectFile.setFileName(projectFile.getFileName() + "-" + projectFile.getFileId());
            }
            projectFile.setProjectId(businessProject.getProjectId());
            AdminStringUtil.setAdminUpdateInfo(projectFile);
            projectFile.setFileId(AdminStringUtil.get32UUID());
            fileNames.add(projectFile.getFileName());
            projectFileService.insert(projectFile);
        }
        // 4. 更新项目信息
        // 判断负责人是否更改
        // 判断项目负责人是否更改和项目附件是否更改
        if (!businessProject.getDutyPersonalName().equals(dutyName)) {
            businessProject.setDutyPersonalName(StringUtils.isEmpty(dutyName) ? "" : dutyName);
        }
        if (!StringUtils.isEmpty(businessProject.getProjectFilesName()) ||
                !businessProject.getProjectFilesName().equals(JSONUtils.toJSONString(fileNames))) {
            businessProject.setProjectFilesName(JSONUtils.toJSONString(fileNames));
        }
        AdminStringUtil.setAdminUpdateInfo(businessProject);
        // 执行更新
        projectService.update(businessProject);
        return ResponseUtil.ok();
    }
}
